#ifndef SYMBOLSTABLE_H_
#define SYMBOLSTABLE_H_

#include <iostream>
#include <string>
#include <ext/hash_map>
#include "HashMapStringFix.h" // defines the namespace which contains hash_map

#include "Token.h"
#include "TableEntry.h"

class SymbolTableInterface
{
public:
	virtual bool search(std::string identifier, TableEntry* &tabEntry) = 0;
	virtual void insert(std::string identifier, TableEntry* tabEntry) = 0;
	
	virtual bool search(Token &tkIdentifier) = 0;
	virtual bool search(Token &tkIdentifier, TableEntry* &tabEntry) = 0;
	virtual void insert(Token &tkIdentifier, TableEntry* tabEntry) = 0;
	
	virtual std::ostream& inserter(std::ostream &os) const =0;
};

typedef HASH_MAP_NAMESPACE::hash_map<std::string, TableEntry*> HashMap;
typedef std::pair<std::string, TableEntry*> HashMapPair;

class SymbolTable : public SymbolTableInterface
{
public:
	SymbolTable();
	virtual ~SymbolTable();
	
	bool search(std::string identifier, TableEntry* &propPtr);
	void insert(std::string identifier, TableEntry* propPtr);
		
	bool search(Token &tkIdentifier);
	bool search(Token &indetifier, TableEntry* &propPtr);
	void insert(Token &token, TableEntry* tabEntry);
	
	std::ostream& inserter(std::ostream &os) const;
	
private:
	HashMap symTable;
};

/**
 * Insertion operator overloading for SymbolTables
 */
inline std::ostream& operator << (std::ostream &os, const SymbolTableInterface &sti) {
	return sti.inserter(os);
}

#endif /*SYMBOLSTABLE_H_*/
